#pragma once
#include "CppSQLite3.h"
#include "../Exception.h"
#include "../ResultSet.h"
#include "../DataBase.h"
#include <sstream>

namespace Arrow_DB_Assistant
{

class SqliteAssistant
	/// MySql data base class
{
	friend class DataBase<SqliteAssistant>;

public:

	SqliteAssistant()
	{
	}

	virtual ~SqliteAssistant()
	{
	}

	void connect(const std::string& server, const std::string& user, const std::string& password, const std::string& database)
	{		
		try
		{
			_db.open(server.c_str());
		}
		catch (CppSQLite3Exception& e)
		{
			std::string strErrMsg = e.errorMessage();
			throw DataBaseError(strErrMsg);
		}
		catch(...)
		{
			throw DataBaseError("Connect Unkonw Exception");
		}
	}
	void execute(const std::string& sql)
	{
		try
		{
			_rsTable = _db.execQuery(sql.c_str());
		}
		catch (CppSQLite3Exception& e)
		{
			std::string strErrMsg = e.errorMessage();
			throw DataBaseError(strErrMsg);
		}
		catch(...)
		{
			throw DataBaseError("Connect Unkonw Exception");
		}
	}

	void populate(ResultTable& rs)
	{
		try
		{
			std::string strValue;
			std::string strField;
			FieldIndex _fieldIndex;

			for (int i = 0; i < _rsTable.numFields(); ++i)
			{
				strField = _rsTable.fieldName(i);
				_fieldIndex[strField] = i;
			}
			rs.setFieldInfo(_fieldIndex);

			while(!_rsTable.eof())
			{
				ResultRow* pRow = NULL;
				pRow = rs.newRow();
				for (FieldIndex::iterator it = _fieldIndex.begin(); it != _fieldIndex.end(); ++it)
				{
					const char* pTmpData = _rsTable.getStringField(it->first.c_str());
					(*pRow)[it->first] = pTmpData;
				}
				rs.addRow(pRow);
				_rsTable.nextRow();
			}

			//for (int nRow = 0; nRow < rsTable.GetRowCount(); ++nRow)
			//{
			//	rsTable.GoRow(nRow);
			//	std::vector<std::string> myRow;
			//	for (int nCol = 0; nCol < rsTable.GetColCount(); ++nCol)
			//	{
			//		strValue = rsTable.GetValue(nCol);
			//		myRow.push_back(strValue.GetBuffer(0));
			//		strValue.ReleaseBuffer();
			//	}
			//	rs.addRow(myRow);
			//}

			//std::map<std::string,size_t> _fieldIndex;
			//for (int nCol = 0; nCol < rsTable.GetColCount(); ++nCol)
			//{
			//	_fieldIndex[rsTable.GetColName(nCol)] = nCol;
			//}
			//rs._fieldIndex = _fieldIndex;
		}
		catch (CppSQLite3Exception& e)
		{
			std::string strErrMsg = e.errorMessage();
			throw DataBaseError(strErrMsg);
		}
		catch(...)
		{
			throw DataBaseError("Connect Unkonw Exception");
		}
	}

protected:

	void close(void)
	{
		try
		{
			_db.close();
		}
		catch (CppSQLite3Exception& e)
		{
			std::string strErrMsg = e.errorMessage();
			throw DataBaseError(strErrMsg);
		}
		catch(...)
		{
			throw DataBaseError("Close Unkonw Exception");
		}
	}

private:
	CppSQLite3DB _db;
	CppSQLite3Query _rsTable;
}; 

}